using System.Collections.Generic;
using Microsoft.Practices.CompositeWeb.Web;
using PageFlowQuickstart.Modules.Customers.BusinessEntities;
using PageFlowQuickstart.Modules.Customers.Constants;
using PageFlowQuickstart.Modules.Customers.Tests.Mocks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using PageFlowQuickstart.CustomersPageFlows;

namespace PageFlowQuickstart.Modules.Customers.Tests
{
    [TestClass]
    public class CustomersControllerFixture
    {
        [TestMethod]
        public void ApproveCurrentCustomerApprovesCurrentCustomerAndUpdatesDataStoreAndNavigatesToApproveCustomer()
        {
            MockPageFlowProvider pageFlowProvider = new MockPageFlowProvider();
            MockPageFlow pageFlow = new MockPageFlow();
            pageFlowProvider.Instance = pageFlow;
            pageFlow.UserData["Customer"] = new Customer(1000, "Enrique", "Gil", false);
            CustomersController controller = new CustomersController(pageFlowProvider);
            controller._customers = new StateValue<List<Customer>>(new List<Customer>(1));
            Customer customerInDataStore = new Customer(1000, "Enrique", "Gil", false);
            controller._customers.Value.Add(customerInDataStore);

            controller.ApproveCurrentCustomer();

            Assert.IsTrue(((Customer)pageFlow.UserData["Customer"]).Approved);
            Assert.IsTrue(customerInDataStore.Approved);
            Assert.AreEqual("ApproveCustomer", pageFlow.NavigateToTransitionName);
        }

        [TestMethod]
        public void FinishCustomerApprovalCompletesPageFlow()
        {
            MockPageFlowProvider pageFlowProvider = new MockPageFlowProvider();
            MockPageFlow pageFlow = new MockPageFlow();
            pageFlowProvider.Instance = pageFlow;
            CustomersController controller = new CustomersController(pageFlowProvider);

            controller.FinishCustomerApproval();

            Assert.IsTrue(pageFlow.CompleteCalled);

        }

        [TestMethod]
        public void CurrentCustomerReturnsCurrentCustomer()
        {
            MockPageFlowProvider pageFlowProvider = new MockPageFlowProvider();
            MockPageFlow pageFlow = new MockPageFlow();
            pageFlowProvider.Instance = pageFlow;
            Customer currentCustomer = new Customer(1000, "Enrique", "Gil", false);
            pageFlow.UserData["Customer"] = currentCustomer;
            CustomersController controller = new CustomersController(pageFlowProvider);

            Customer result = controller.CurrentCustomer;

            Assert.AreEqual(currentCustomer.Id, result.Id);
            Assert.AreEqual(currentCustomer.Name, result.Name);
            Assert.AreEqual(currentCustomer.LastName, result.LastName);
            Assert.AreEqual(currentCustomer.Approved, result.Approved);
        }

        [TestMethod]
        public void CurrentCustomerReturnsNullIfAllCustomersAreApproved()
        {
            MockPageFlowProvider pageFlowProvider = new MockPageFlowProvider();
            MockPageFlow pageFlow = new MockPageFlow();
            pageFlowProvider.Instance = pageFlow;
            CustomersController controller = new CustomersController(pageFlowProvider);
            controller._customers = new StateValue<List<Customer>>(new List<Customer>(1));
            controller._customers.Value.Add(new Customer(1000, "Enrique", "Gil", true));
            
            Customer result = controller.CurrentCustomer;

            Assert.IsNull(result);
        }
        
        [TestMethod]
        public void StartCustomersApprovalStartsCustomersApprovalPageFlowAndPutNextCustomerInState()
        {
            MockPageFlowProvider pageFlowProvider = new MockPageFlowProvider();
            MockPageFlow pageFlow = new MockPageFlow();
            pageFlowProvider.Instance = pageFlow;
            CustomersController controller = new CustomersController(pageFlowProvider);
            controller._customers = new StateValue<List<Customer>>(new List<Customer>(2));
            controller._customers.Value.Add(new Customer(1001, "Paul", "West", true));
            Customer nonApprovedCustomer = new Customer(1000, "Enrique", "Gil", false);
            controller._customers.Value.Add(nonApprovedCustomer);

            controller.StartCustomerApproval();

            Assert.AreEqual(typeof(CustomersApprovalXmlPageFlow), pageFlowProvider.TypeRequested);
            Assert.IsTrue(pageFlow.StartCalled);
            Assert.AreEqual(nonApprovedCustomer.Id, controller.CurrentCustomer.Id);
            Assert.AreEqual(nonApprovedCustomer.Name, controller.CurrentCustomer.Name);
            Assert.AreEqual(nonApprovedCustomer.LastName, controller.CurrentCustomer.LastName);
            Assert.AreEqual(nonApprovedCustomer.Approved, controller.CurrentCustomer.Approved);
        }
    }
}
